/*
gcc -g -Wall -L /usr/local/lib -lev sock.h evServer.c -o evserver

*/

#include<ev.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include "sock.h"

ev_io *accept_watcher;
struct ev_loop *main_loop;
int listen_fd;//声明 服务器监听fd


void setnonblocking(int sock);
void accept_cb(struct ev_loop *main_loop, ev_io * io_w, int e);
void send_cb(struct ev_loop *main_loop, ev_io * io_w, int e);

int main(){

	main_loop = ev_default_loop(0);

 	create_bind_listen(&listen_fd, 9999, 5);
 	
 	int reuse = 1;
 	if(setsockopt(listen_fd,SOL_SOCKET ,SO_REUSEADDR,&reuse,sizeof(reuse)) != 0) {  
        printf("setsockopt error in reuseaddr[%d]\n", listen_fd);  	
    }  
 	setnonblocking(listen_fd);
 	
 	accept_watcher = (struct ev_io *)malloc(sizeof(struct ev_io));
 	ev_io_init (accept_watcher, accept_cb, listen_fd, EV_READ);
 	ev_io_start(main_loop,accept_watcher);

    ev_run(main_loop,0);
    
	return 0;
}

void setnonblocking(int sock){
   int opts;
   opts = fcntl(sock, F_GETFL);
   if(opts < 0){
      perror("fcntl(sock, GETFL)");
      exit(1);
   }
   opts = opts | O_NONBLOCK;
   if(fcntl(sock, F_SETFL, opts) < 0){
      perror("fcntl(sock,SETFL,opts)");
      exit(1);
   }
}

void accept_cb(struct ev_loop *main_loop,ev_io *io_w,int e){
	int conn_fd;//声明 连接的fd，也就是accept之后的
 	struct sockaddr_in client_addr;
 	socklen_t len = sizeof(client_addr);
 	conn_fd = accept(io_w->fd, (struct sockaddr *)&client_addr, &len);
 	setnonblocking(conn_fd);

	if(conn_fd > 0){
		 printf("got connection from ip:%s, port:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); 
		 ev_io *send_watcher = (struct ev_io *)malloc(sizeof(struct ev_io));
		 ev_io_init (send_watcher, send_cb, conn_fd, EV_WRITE);
		 ev_io_start(main_loop, send_watcher);
	}
	else if(conn_fd < 0){
		printf("connection error ...\n");
	}
}

void send_cb(struct ev_loop *main_loop, ev_io *io_w, int e){
	printf("sock can write\n");
	char path[512];
	printf("input the path:");
	scanf("%s",path);
	path[strlen(path)]='\0';
	printf("%s-\n",path);
	Send(path, io_w->fd);
}
